#ifndef _LOG_H_
#define _LOG_H_
#include "common/base_type.h"
#include <string.h>

#ifndef LOG_TAG
#define LOG_TAG "NO_TAG"
#endif
/**
 * 日志输出级别
 */
enum TLogLevelTag
{
    kLogLevelSilent  = 0,  ///< 静默级别
    kLogLevelAssert  = 1,  ///< 断言级别
    kLogLevelError   = 2,  ///< 错误级别
    kLogLevelWarning = 3,  ///< 警告级别
    kLogLevelInfo    = 4,  ///< 信息级别
    kLogLevelDebug   = 5,  ///< 调试级别
    kLogLevelTrace   = 6,  ///< 追踪级别
};
typedef enum TLogLevelTag TLogLevel;

#define __FILENAME__ strrchr(__FILE__,'\\')?strrchr(__FILE__,'\\')+1:__FILE__

#define LOG(level, tag, fmt, ...) TLog((UInt8)level, (Int8 *)tag, (Int8 *)__FILENAME__, (Int8 *)__FUNCTION__, (Int32)__LINE__, (Int8 *)fmt, ##__VA_ARGS__)
#define LOG_S(fmt, ...) TLog(kLogLevelSilent, (Int8 *)LOG_TAG, (Int8 *)__FILENAME__, (Int8 *)__FUNCTION__, (Int32)__LINE__, (Int8 *)fmt, ##__VA_ARGS__)
#define LOG_A(fmt, ...) TLog(kLogLevelAssert, (Int8 *)LOG_TAG, (Int8 *)__FILENAME__, (Int8 *)__FUNCTION__, (Int32)__LINE__, (Int8 *)fmt, ##__VA_ARGS__)
#define LOG_E(fmt, ...) TLog(kLogLevelError, (Int8 *)LOG_TAG, (Int8 *)__FILENAME__, (Int8 *)__FUNCTION__, (Int32)__LINE__, (Int8 *)fmt, ##__VA_ARGS__)
#define LOG_W(fmt, ...) TLog(kLogLevelWarning, (Int8 *)LOG_TAG, (Int8 *)__FILENAME__, (Int8 *)__FUNCTION__, (Int32)__LINE__, (Int8 *)fmt, ##__VA_ARGS__)
#define LOG_I(fmt, ...) TLog(kLogLevelInfo, (Int8 *)LOG_TAG, (Int8 *)__FILENAME__, (Int8 *)__FUNCTION__, (Int32)__LINE__, (Int8 *)fmt, ##__VA_ARGS__)
#define LOG_D(fmt, ...) TLog(kLogLevelDebug, (Int8 *)LOG_TAG, (Int8 *)__FILENAME__, (Int8 *)__FUNCTION__, (Int32)__LINE__, (Int8 *)fmt, ##__VA_ARGS__)
#define LOG_T(fmt, ...) TLog(kLogLevelTrace, (Int8 *)LOG_TAG, (Int8 *)__FILENAME__, (Int8 *)__FUNCTION__, (Int32)__LINE__, (Int8 *)fmt, ##__VA_ARGS__)
#define LOG_HEX(lvl, buf_tag, buf, buf_size) TLogHex(lvl, (Int8 *)LOG_TAG, (Int8 *)__FILENAME__, (Int8 *)__FUNCTION__, (Int32)__LINE__, (Int8 *)buf_tag, (UInt8 *)buf, buf_size)
#define LOG_STR(lvl, buf_tag, buf, buf_size) TLogStr(lvl, (Int8 *)LOG_TAG, (Int8 *)__FILENAME__, (Int8 *)__FUNCTION__, (Int32)__LINE__, (Int8 *)buf_tag, (UInt8 *)buf, buf_size)

/**
 * 格式化输出日志
 * @param level: 日志级别,参考 TALogLevelEnum
 * @param tag: 日志标签
 * @param file_name: 文件名,以'\0'结尾
 * @param func_name: 函数名,以'\0'结尾
 * @param line: 行数
 * @param format: 格式化的字符串
 */
void TLog(UInt8 level, const Int8 *tag,
          const Int8 *file_name, const Int8 *func_name, Int32 line,
          const Int8 *format, ...);

/**
 * 以HEX格式打印16进制数据
 * @notice: 最大输出4K的原始数据，超过4K的数据会被丢弃
 * @param level: 日志级别,参考 TALogLevelEnum
 * @param tag: 日志标签
 * @param file_name: 文件名,以'\0'结尾
 * @param func_name: 函数名,以'\0'结尾
 * @param line: 行数
 * @param buf_tag: 数据标签,以'\0'结尾
 * @param buf: 待输出的数据内容
 * @param buf_size: 数据大小，最大支持4K数据的输出
 */
void TLogHex(UInt8 level, const Int8 *tag,
             const Int8 *file_name, const Int8 *func_name, Int32 line,
             const UInt8 *buf_tag,
             const UInt8 *buf, Int16 buf_size);

/**
 * 以STR格式打印16进制数据
 * @notice: 最大输出4K的原始数据，超过4K的数据会被丢弃
 * @param level: 日志级别,参考 TALogLevelEnum
 * @param tag: 日志标签
 * @param file_name: 文件名,以'\0'结尾
 * @param func_name: 函数名,以'\0'结尾
 * @param line: 行数
 * @param buf_tag: 数据标签,以'\0'结尾
 * @param buf: 待输出的数据内容
 * @param buf_size: 数据大小，最大支持4K数据的输出
 */
void TLogStr(UInt8 level, const Int8 *tag,
             const Int8 *file_name, const Int8 *func_name, Int32 line,
             const UInt8 *buf_tag,
             const UInt8 *buf, Int16 buf_size);

#endif  ///< _LOG_H_
